#ifndef FLASH_H
#define FLASH_H

#include <stdint.h>
/*
256KB flash空间分配：
                start addr    end addr    size
bootloader :    0x08000000    0x08003FFF  16KB
user data  :    0x08003FFF    0x08007FFF  16KB   (用户数据)
active app :    0x08008000    0x0803BFFF  224KB  (当前运行的APP)

扇区0 0x0800 0000 - 0x0800 3FFF 16KB
扇区1 0x0800 4000 - 0x0800 7FFF 16KB
扇区2 0x0800 8000 - 0x0800 BFFF 16KB
扇区3 0x0800 C000 - 0x0800 FFFF 16KB
扇区4 0x0801 0000 - 0x0801 FFFF 64KB
扇区5 0x0802 0000 - 0x0803 FFFF 128KB

*/

#define KB 1024ul

/* FMC sector information */
typedef struct
{
    uint32_t sector_name;                                         /*!< the name of the sector */
    uint32_t sector_num;                                          /*!< the number of the sector */
    uint32_t sector_size;                                         /*!< the size of the sector */
    uint32_t sector_start_addr;                                   /*!< the start address of the sector */
    uint32_t sector_end_addr;                                     /*!< the end address of the sector */
} flash_sector_info_struct;
/* sector size */
#define SIZE_16KB                  ((uint32_t)0x00004000U)        /*!< size of 16KB*/
#define SIZE_64KB                  ((uint32_t)0x00010000U)        /*!< size of 64KB*/
#define SIZE_128KB                 ((uint32_t)0x00020000U)        /*!< size of 128KB*/
#define SIZE_256KB                 ((uint32_t)0x00040000U)        /*!< size of 256KB*/

/* FMC BANK address */
#define FLASH_START_ADDRESS          FLASH_BASE                               /*!< FMC start address */
#define FLASH_BANK0_START_ADDRESS    FLASH_START_ADDRESS                      /*!< FMC BANK0 start address */
#define FLASH_BANK1_START_ADDRESS    ((uint32_t)0x08100000U)                  /*!< FMC BANK1 start address */
#define FLASH_SIZE                   (*(uint16_t *)0x1FFF7A22U)               /*!< FMC SIZE */
#define FLASH_END_ADDRESS            (FLASH_BASE + (FLASH_SIZE * 1024) - 1)   /*!< FMC end address */
#define FLASH_MAX_END_ADDRESS        ((uint32_t)0x08300000U)                  /*!< FMC maximum end address */

/* FMC error message */
#define FLASH_WRONG_SECTOR_NAME      ((uint32_t)0xFFFFFFFFU)        /*!< wrong sector name*/
#define FLASH_WRONG_SECTOR_NUM       ((uint32_t)0xFFFFFFFFU)        /*!< wrong sector number*/
#define FLASH_INVALID_SIZE           ((uint32_t)0xFFFFFFFFU)        /*!< invalid sector size*/
#define FLASH_INVALID_ADDR           ((uint32_t)0xFFFFFFFFU)        /*!< invalid sector address*/

#define USER_DATA_ADDR_BASE 0x08004000
#define FLASH_ERASE_ADDR_BASE 0x08004000
#define FLASH_ERASE_BYTES ((512 - 16) * KB)

#define ACTIVE_APP_ADDR_BASE 0x08008000
#define ACTIVE_APP_MAX_BYTES (224 * KB)

#define APP_ADDR_BASE 0x08004800

extern void Flash_program(uint32_t * data,uint32_t addressx);
extern int Flash_erase_onePage(uint32_t addr);
extern void fmc_read_32bit_data(uint32_t address, uint16_t length, int32_t *data_32);
extern int fmc_write_32bit_data_with_sector_erased(uint32_t address, uint16_t length,
                                            const uint32_t *data_32);
#endif
